package com.nanbei.rabbit.producer.confirm;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Objects;

/**
 * @ClassDescription:  生产者确认机制
 * @JdkVersion: 1.8
 * @Author: libs
 * @Created: 2024/8/30 10:58
 */
@Configuration
public class RabbitMqConfiguration {

    /**
     * 定义 RabbitTemplate Bean
     * @param connectionFactory  mq 的连接工厂，由spring Boot根据连接的配置信息实现了自动化配置，在spring容器中是直接存在connectionFactory对象。
     * @return rabbitTemplate
     */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        /**
         * correlationData – 回调的相关数据。
         * ack – true 表示 ack，false 表示 nack
         * cause – 可选原因，对于 nack，如果可用，否则为 null。
         */
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack){
                System.out.println("消息成功发送给交换机。。。");
            }else {
                System.out.println("消息发送至交换机失败，失败原因为："+cause);
                if (correlationData != null){
                    String id = correlationData.getId();
                    System.out.println("msgId:" + id);
                }
                // todo 根据消息的id查询数据库，获取消息的内容，然后进行重新发送 ，
                //  表中需要设计：最大发送次数的字段 ，消息的状态
                // 消息的最大发送次数(3次)，判断消息的实际发送次数是否大于最大发出次数，如果大于就不会进行重新发送
                // 每次发送时需要对数据库表中 最大发送次数的字段 的数据进行自增
            }
        });

        // 给rabbitmq 绑定回退机制
        // 消息没有正常从交换机发送给队列的时候会被调用   改方法调用的概率极低的（除非路由规则写错）
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setReturnsCallback(returned -> {
            System.out.println("消息发送到队列失败");
            String msg = new String(returned.getMessage().getBody());
            System.out.println("msg: "+msg +",replyCode: "+returned.getReplyCode()
                    +",replyText: "+returned.getReplyText() +",exchange: "+returned.getExchange()
                    +",routingKey: "+returned.getRoutingKey() );
        });
       /* rabbitTemplate.setReturnsCallback((message, replyCode, replyText, exchange, routingKey) -> {
            System.out.println("消息发送到队列失败");
            String msg = new String(message.getBody());
            System.out.println("msg: "+msg +",replyCode: "+replyCode +",replyText: "+replyText +",exchange: "+exchange +",routingKey: "+routingKey );
        });*/
        return  rabbitTemplate;
    }
}
